home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / gem / l_1199 / 969 < prev    next >
Internet Message Format  |  1994-08-27  |  6KB

  1. Date: Fri, 22 Jul 94 03:16 CDT
  2. From: ekl@sdf.lonestar.org (Evan K. Langlois)
  3. To: gem-list@world.std.com
  4. Subject: BUTTON CODE
  5. Precedence: bulk
  6.  
  7.  
  8. /* NOTE  This program uses printf, and it really shouldn't.  But I want
  9.    you to compile this and see that you really can wait on any buttons
  10.    and that a right-left combination is NOT needed.  I used printf so
  11.    I wouldn't have to post a RSC file.  This program is only meant to
  12.    demonstrate how to recieve mouse button events.  It is NOT meant to
  13.    show how to properly code a GEM application - see ST-Pro-GEM for good
  14.    GEM programming.
  15. */
  16.  
  17. #include <osbind.h>
  18. #include <gemfast.h>
  19. #include <aesbind.h>
  20. #include <stdio.h>
  21.  
  22. void main (void) {
  23.  
  24.   register int i, bb;
  25.   int quit = 0, mes[8], ky, t, press, x, y, b, d, nb, k, rc, app_id;
  26.  
  27.   app_id = appl_init();
  28.  
  29. /* This may help multitasking, and/or the double-click-event bug, and it
  30.    sets up some defaults, like starting button mask.  Its not needed */
  31.  
  32.   evnt_multi(0x23,1,1,1,0,0,0,0,0,0,0,0,0,0,mes,150L,&x,&y,&nb,&k,&ky,&t);
  33.  
  34.   while (!quit) {
  35.  
  36. /* HOW TO WAIT ON ANY BUTTON !
  37.  
  38.    The second parameter to evnt_multi tells how many button clicks to
  39.    wait for.  This is the maximum number, so make it big.  If you want to
  40.    recieve a double click, make it at least 2.  Big numbers are no problem.
  41.    The high byte is set ON (OR with 0x0100 or add 256) to make this a
  42.    reverse button event - we wait for a negative condition.  I'm not sure
  43.    if GEM will still delay for a second click if you set the low byte to 1,
  44.    and we NEED this delay for "presses" so leave the byte at 2 to be safe.
  45.  
  46.    The third parameter tells the mask of buttons that you are waiting on.
  47.    ALL BUTTONS ARE WAITED FOR!  You wait for all buttons, not either button.
  48.    Normally you use 0x01 for the left button, but when using the negative
  49.    event, you can handle more buttons than one, so make it 0x7F for all 8!
  50.  
  51.    The third is a button mask, 0 for up, 1 for down, for each button, same
  52.    as the button return word, and the button mask in the previous parameter.
  53.    Normally this is a 1, waiting for the left mouse button to be down.  In
  54.    this trick you make it a 0 (all buttons up).
  55.  
  56.    The trick is simple, wait for ALL buttons to NOT be up.  The event fires
  57.    when ALL the buttons are not up - or when any one button is down.  Now,
  58.    a common mistake is to leave the third parameter a constant, which means
  59.    the evnt_multi falls through as long as the person holds the button down.
  60.    Make the parameter the old button mask, and you'll get an event when any
  61.    one button changes state.  Note that you'll get two events for one click
  62.    unless you change the button mask and remember that on a normal click,
  63.    the mouse has been checked for a double-click, so &b is when the event
  64.    occured, not the current button state.
  65.  
  66.    By using graf_mkstate to poll the current state of the button, we can
  67.    tell if the button is already up.  If its already released, then we have
  68.    a single click, and we change our mask so that we don't get a button
  69.    up event.  Otherwise, we see if there is a draggable object or menu.
  70. */
  71.         rc = evnt_multi (0x03, 0x102,0x7F,nb, 0,0,0,0,0, 0,0,0,0,0, mes,
  72. 0L, &x, &y, &b, &k, &ky, &t);
  73.  
  74.         if (rc & MU_KEYBD)   /* Keyboard event, quit app */
  75.                 quit = 1;
  76.  
  77.         if (rc & MU_BUTTON) {
  78.                 /* See what window to "send" the click to here, with
  79.                  * wind_find() and a custom lookup - how is up to you.
  80.                  *
  81.                  * graf_mkstate() is called here because it sets the
  82.                  * evnt_multi input button state and gives us the
  83.                  * current state to compare to the evnt_multi output
  84.                  */
  85.  
  86.                 graf_mkstate (&d,&d,&press,&d); /* New button state */
  87.  
  88.  
  89.                 /* Here we test and compare button masks, bit-by-bit! */
  90.  
  91.                 for (i=0; i < 8; i++) {
  92.                   bb = (1 << i);                  /* A  mask ! */
  93.                   if ((nb & bb) != (b & bb)) {    /* An event? */
  94.                     if (b & bb)
  95.                       if (press & bb)
  96.                         printf ("Press   button #%d @ %d,%d\n",i,x,y);
  97.                       else if (t > 1)
  98.                         printf ("D-Click button #%d @ %d,%d\n",i,x,y);
  99.                       else
  100.                         printf ("Click   button #%d @ %d,%d\n",i,x,y);
  101.                     else
  102.                       printf ("Release button #%d @ %d,%d\n",i,x,y);
  103.                   }
  104.                 }
  105.                 nb = press;
  106.         }
  107.   }
  108.   appl_exit();
  109.   Pterm0();
  110. }
  111.  
  112.  
  113. /* A press means begin drag or group select (button 0/left) or pop-up a
  114.  * menu (button 1/right) or it may mean to begin some rectangle tricks. A
  115.  * graphics program would use a press to turn on mouse rectangles, and
  116.  * would apply a brush when the rectangle event fires, and would turn off
  117.  * the rectangle event handling when a release event occurs.  A release
  118.  * event signals where a pop-up menu was selected, or where an item was
  119.  * dropped.
  120.  *
  121.  * Remember that you did not get an event unless the button mask put in
  122.  * to evnt_multi is different from that coming out of evnt_multi.
  123.  *
  124.  * A window top is a click if there is a selectable and completely
  125.  * UNOBSCURED object under the mouse pointer in the window being topped.
  126.  * Otherwise top the window!   Objects must be completely visible!
  127.  *
  128.  *
  129.  * A press can wait on rectangles do the operation on a release within
  130.  * the object, while entering and exiting the object selects and deselects
  131.  * the object, much like form_do() - try it!
  132.  *
  133.  * Don't call graf_mkstate or another polling routine - always use the
  134.  * mouse coordinates at the time of the event!  The code above is very
  135.  * non-modal.  You can pop-up a menu with a right button, then realizing
  136.  * you should have selected an icon, you click it with the left button,
  137.  * then release the right button on the menu item you prefer.  Button
  138.  * events are completely independant!  You are also free to allow the
  139.  * right button OR left button to select buttons (nice for left handed
  140.  * users).
  141.  *
  142.  * Enjoy the code!
  143.  */
  144.  
  145.